//
//  drumsetController.m
//  rockband2garageband
//
//  Created by Sid Stamm on 7/25/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "DrumsetController.h"
#import "Drumset.h"

@implementation DrumsetController

- (id) init
{
    self = [super init];
    if (self != nil) {        
/*        
        drumset = [[Drumset alloc] init];
        usbcontroller = [[DrumsetUSBController alloc] init];
        //TODO: register callback so we know when the drums are connected
        [usbcontroller runAndNotify:self];
 */
    }
    return self;
}

- (void) awakeFromNib
{
    //IOReturn ioReturnValue = kIOReturnSuccess;
    
    // insert code here...
    CFShow(CFSTR("Hello, World!\n"));
    
    // look in USB registry for a Drumset, make an instance, and set a run-loop 
    // to watch its inputs
    //deviceInterface = findHIDDrumset();
    deviceInterface = [Drumset findHIDDrumset];
    
    if(deviceInterface != NULL) {
        
        drumset = [[Drumset alloc] initWithDeviceInterface:deviceInterface];
        [drumset setListener:self selector:@selector(updateDrumdata)];
        [self updateDrumdata];
        /*
        [drumset testQueueCallback];  //run and listen at queue for drum hits
        [drumset teardownQueueCallback];
        
        ioReturnValue = (*deviceInterface)->close (deviceInterface);
        printf ("Close result = %d\n", ioReturnValue);
        
        // Release the device interface
        (*deviceInterface)->Release (deviceInterface); 
        */
    }
}

- (void) dealloc
{
    IOReturn ioReturnValue = kIOReturnSuccess;

    if(deviceInterface != NULL) {
        [drumset teardownQueueCallback];
        ioReturnValue = (*deviceInterface)->close(deviceInterface);
        printf("Close result = %d\n", ioReturnValue);
        (*deviceInterface)->Release(deviceInterface);
    }
    return [super dealloc];
}

- (void)notifyUSBDrumsetAdded 
{
    printf("USB Drumset Added!");
    [connectedIndicator setStringValue:@"Connected"];
    [connectedIndicator setIntValue:1];
    [connectedIndicator setCriticalValue:0];
    [connectedSpinner stopAnimation:nil];
}

- (void)notifyUSBDrumsetRemoved 
{
    printf("USB Drumset REMOVED!");
    [connectedIndicator setStringValue:@"Disconnected"];
    [connectedIndicator setIntValue:1];
    [connectedIndicator setCriticalValue:1];
    [connectedSpinner startAnimation:nil];

}

- (void)updateDrumdata 
{
    //fetch the drum states from the drumset
    [red_drum_value setFloatValue:[drumset red_drum_value]];
    [yellow_drum_value setFloatValue:[drumset yellow_drum_value]];
    [blue_drum_value setFloatValue:[drumset blue_drum_value]];
    [green_drum_value setFloatValue:[drumset green_drum_value]];
    [pedal_drum_value setFloatValue:[drumset pedal_drum_value]];
    
    //fetch the midi note data
    [yellow_drum_channel setIntValue:[drumset getMidiNote:YELLOW_DRUM]];
    [yellow_drum_stepper setIntValue:[drumset getMidiNote:YELLOW_DRUM]];
    
    [red_drum_channel setIntValue:[drumset getMidiNote:RED_DRUM]];
    [red_drum_stepper setIntValue:[drumset getMidiNote:RED_DRUM]];

    [blue_drum_channel setIntValue:[drumset getMidiNote:BLUE_DRUM]];
    [blue_drum_stepper setIntValue:[drumset getMidiNote:BLUE_DRUM]];

    [green_drum_channel setIntValue:[drumset getMidiNote:GREEN_DRUM]];
    [green_drum_stepper setIntValue:[drumset getMidiNote:GREEN_DRUM]];

    [pedal_drum_channel setIntValue:[drumset getMidiNote:PEDAL_DRUM]];
    [pedal_drum_stepper setIntValue:[drumset getMidiNote:PEDAL_DRUM]];
}

/**
 * Delegate method for the drum control changes
 */
- (IBAction) drumChannelChanged: (id) sender
{
    [self drumChannelChanged:((drum_index_t)[sender tag]) toValue:[sender intValue]];
}

- (void) drumChannelChanged:(drum_index_t)index toValue:(int)val
{
    [drumset setMidiNote:val forDrum:index];
    switch(index) {
        case RED_DRUM:
            [red_drum_channel setIntValue:val];
            [red_drum_stepper setIntValue:val];
            break;
        case YELLOW_DRUM:
            [yellow_drum_channel setIntValue:val];
            [yellow_drum_stepper setIntValue:val];
            break;
        case BLUE_DRUM:
            [blue_drum_channel setIntValue:val];
            [blue_drum_stepper setIntValue:val];
            break;
        case GREEN_DRUM:
            [green_drum_channel setIntValue:val];
            [green_drum_stepper setIntValue:val];
            break;
        case PEDAL_DRUM:
            [pedal_drum_channel setIntValue:val];
            [pedal_drum_stepper setIntValue:val];
            break;
    }
    
    //update the model
//	[self changeMidiNotes];
//    [self updateDrumdata];
}

- (void)changeMidiNotes 
{
    [drumset setMidiNote:[yellow_drum_channel intValue] forDrum:YELLOW_DRUM];
    [drumset setMidiNote:[green_drum_channel intValue] forDrum:GREEN_DRUM];
    [drumset setMidiNote:[blue_drum_channel intValue] forDrum:BLUE_DRUM];
    [drumset setMidiNote:[pedal_drum_channel intValue] forDrum:PEDAL_DRUM];
}

@end
